home *** CD-ROM | disk | FTP | other *** search
/ APDL Other Worlds / APDL Other Worlds Collection.iso / SF3000 / Extras / CBlibrary / c / FilePerc < prev    next >
Encoding:
Text File  |  2003-10-16  |  5.0 KB  |  175 lines

  1. /*
  2.  * CBLibrary - FilePerc
  3.  * Copyright (C) 2003  Chris Bazley
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2.1 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  */
  19.  
  20. /* Displays % hourglass and watches for ESCAPE during file operations */
  21.  
  22. /* ANSI library files */
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <assert.h>
  27.  
  28. /* RISC OS library files */
  29. #include "kernel.h"
  30. #include "flex.h"
  31.  
  32. /* Other headers */
  33. #include "Macros.h"
  34. #include "msgtrans.h"
  35. #include "hourglass.h"
  36. #include "timer.h"
  37. #include "FedCompMT.h"
  38. #ifndef COMP_OPS_ONLY
  39. #include "LoadSaveMT.h"
  40. #endif
  41. #include "AbortFop.h"
  42. #include "FilePerc.h"
  43.  
  44. static volatile bool time_up = true;
  45. static bool at_exit = false;
  46.  
  47. extern _kernel_oserror shared_err_block;
  48.  
  49. /* ----------------------------------------------------------------------- */
  50. /*                       Function prototypes                               */
  51.  
  52. static void ensure_timer_removed(void);
  53.  
  54. /* ----------------------------------------------------------------------- */
  55. /*                         Public functions                                */
  56.  
  57. _kernel_oserror *perc_operation(int type, const char *file_path, unsigned int file_type, flex_ptr buffer_anchor)
  58. {
  59.   assert(type == FILEPERC_OP_DECOMP || type == FILEPERC_OP_COMP 
  60. #ifndef COMP_OPS_ONLY
  61.   || type == FILEPERC_OP_LOAD || type == FILEPERC_OP_SAVE
  62. #endif
  63.   );
  64.  
  65.   /* enable escape key & reset escape detection */
  66.   if(_kernel_osbyte(229, 0, 0) == _kernel_ERROR)
  67.     return _kernel_last_oserror();
  68.   _kernel_escape_seen();
  69.  
  70.   hourglass_on();
  71.  
  72.   if(!at_exit) {
  73.     atexit(ensure_timer_removed);
  74.     at_exit = true;
  75.   }
  76.  
  77.   FILE **handle = NULL;
  78.   _kernel_oserror *err = NULL;
  79.   int esc_seen = 0;
  80.  
  81.   do {
  82.     time_up = false;
  83.     err = timer_register(&time_up, 10); /* break 10 times a second to update hourglass */
  84.     if(err != NULL)
  85.       time_up = true; /* could not set up timer event */
  86.     else {
  87.       switch(type) {
  88. #ifndef COMP_OPS_ONLY
  89.         case FILEPERC_OP_LOAD:
  90.           err = load_fileM(file_path, buffer_anchor, &time_up, &handle, FLAG_SET(file_type, 1u<<31));
  91.           break;
  92.  
  93.         case FILEPERC_OP_SAVE:
  94.           err = save_fileM(file_path, file_type, buffer_anchor, &time_up, &handle, FLAG_SET(file_type, 1u<<31));
  95.           break;
  96. #endif
  97.         case FILEPERC_OP_DECOMP:
  98.           err = load_compressedM(file_path, buffer_anchor, &time_up, &handle);
  99.           break;
  100.  
  101.         case FILEPERC_OP_COMP:
  102.           err = save_compressedM(file_path, file_type, buffer_anchor, &time_up, &handle);
  103.           break;
  104.  
  105.       }
  106.       ensure_timer_removed(); /* in case OS_CallAfter event still pending */
  107.  
  108.       if(handle != NULL) {
  109.         unsigned int perc;
  110.         switch(type) {
  111. #ifndef COMP_OPS_ONLY
  112.           case FILEPERC_OP_LOAD:
  113.           case FILEPERC_OP_SAVE:
  114.             perc = get_loadsave_perc(&handle);
  115.             break;
  116. #endif
  117.           case FILEPERC_OP_DECOMP:
  118.             perc = get_decomp_perc(&handle);
  119.             break;
  120.  
  121.           case FILEPERC_OP_COMP:
  122.             perc = get_comp_perc(&handle);
  123.             break;
  124.  
  125.           default:
  126.             perc = 0;
  127.             break;
  128.         }
  129.         hourglass_percentage(perc);
  130.       }
  131.  
  132.       esc_seen = _kernel_escape_seen(); /* check for escape condition */
  133.     }
  134.   } while(handle != NULL && err == NULL && !esc_seen);
  135.   hourglass_off();
  136.  
  137.   /* disable escape key & clear any escape condition */
  138.   if(_kernel_osbyte(229, 1, 0) == _kernel_ERROR
  139.   || _kernel_osbyte(124, 0, 0) == _kernel_ERROR) {
  140.     if(err == NULL)
  141.       err = _kernel_last_oserror();
  142.   }
  143.  
  144.   /* If stopped in mid-operation then close it down */
  145.   if(handle != NULL)
  146.     abort_file_op(&handle);
  147.  
  148.   /* Inform the user if we stopped due to them pressing ESCAPE */
  149.   if(esc_seen && err == NULL) {
  150.     WRITE_ERR(shared_err_block, "Escape");
  151.     err = &shared_err_block;
  152.   }
  153.  
  154.   /* If error, then free any allocated block */
  155.   if((type == FILEPERC_OP_LOAD || type == FILEPERC_OP_DECOMP) && err != NULL && *buffer_anchor != NULL) {
  156.     flex_free(buffer_anchor);
  157.     *buffer_anchor = NULL;
  158.   }
  159.  
  160.   return err; /* success */
  161. }
  162.  
  163. /* ----------------------------------------------------------------------- */
  164. /*                         Private functions                               */
  165.  
  166. static void ensure_timer_removed(void)
  167. {
  168.   /* Last-ditch effort to remove OS_CallAfter routine, if still pending */
  169.   if(!time_up) {
  170.     timer_deregister(&time_up);
  171.     /* (suppress errors, as event may occur between check and removal) */
  172.     time_up = true;
  173.   }
  174. }
  175.